package com.flesler.actoras.core
{
	import flash.events.EventDispatcher;
	
	// TODO: How to initialize actors? anonymous messages?
	
	public class ActorBroker extends EventDispatcher
	{
		private var map:Object = {};
		
		public function ActorBroker()
		{
		}
		
		// Exposed functionality
		
		public function register(actor:Actor):void
		{
			var name:String = actor.name;
			
			getAllByName(name).push(actor);

			actor.addEventListener(ActorEvent.MESSAGE_SENT, sendFromEvent);
			actor.addEventListener(ActorEvent.ADDED, registerFromEvent);
		}
		
		public function unregister(actor:Actor):void
		{
			var actors:Array = getAllByName(actor.name);
			var i:int = actors.indexOf(actor);
			if (i !== -1)
				actors.splice(i, 1);
		}
		
		public function hasAnyOf(name:String):Boolean
		{
			return getAllByName(name).length > 0;
		}
		
		public function getAllByName(name:String):Array
		{
			return map[name] || (map[name] = []);
		}
		
		public function getByName(name:String):Actor
		{
			return getAllByName(name)[0];
		}
		
		public function send(receiver:String, sender:String, ...args):void
		{
			sendArgs(receiver, sender, args);
		}
		
		// Private utilities
		
		private function registerFromEvent(e:ActorEvent):void
		{
			register(e.actor);
		}
		
		private function sendArgs(receiver:String, sender:String, args:Array):void
		{
			var e:ActorEvent = new ActorEvent(
				ActorEvent.MESSAGE_RECEIVED, args, sender
			);
			
			for each (var actor:Actor in getAllByName(receiver))
				actor.dispatchEvent(e);
		}
		
		
		private function sendFromEvent(e:ActorEvent):void
		{
			var sender:Actor = e.target as Actor;
			sendArgs(e.actorName, sender.name, e.args);
		}
	}
}